<?php
/**
 * Classe responsável pelo gerenciamento do datagrid
 * 
 * @author Cristiano Gomes
 * @version 0.1
 */
class DataGrid{

	private $grid_campos = array();
	private $chave_primaria;
	private $acoes_permitidas = array();
	private $grid_filtros = array();
	private $grid_pagina;
	private $extensao_paginacao = 5;
	private $itens_por_pagina = 20;
	private $ctrl; 
	private $ordenacao;

	public function AjustaControle(Controle $ctrl){
		$this->grid_campos 			= $ctrl->GridCampos();
		$this->chave_primaria 		= $ctrl->ChavePrimaria();
		$this->acoes_permitidas 	= (sizeof($ctrl->AcoesPermitidas()) == 0 ) ? array('editar', 'excluir') : $ctrl->AcoesPermitidas();
		$this->grid_filtros			= $ctrl->GridFiltros();
		$this->grid_pagina			= $ctrl->GridPagina();
		$this->extensao_paginacao 	= $ctrl->GridExtensaoPaginacao();
		$this->itens_por_pagina		= $ctrl->ItensPorPagina();
		$this->ctrl					= $ctrl;
		$this->ordenacao			= $ctrl->Ordenacao();
	}

	public function GerarPaginacao($atual, $em_volta, $primeira, $ultima){
		$anterior = ($atual > 1) ? $atual - 1 : 1;
		$proxima = ($atual < $ultima) ? $atual + 1 : $ultima;

		$nome_pagina = strtolower($this->ctrl->GetSistema()->GetPaginaAtual()->Nome());
		$lista = '<ul id="paginacao">
					<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $primeira . ', \'' . $nome_pagina . '\');"><img src="shell/img/primeira.png" border="0"></a></li>
					<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $anterior . ', \'' . $nome_pagina . '\')"><img src="shell/img/anterior.png" border="0"></a></li>';

		foreach($em_volta as $pag){
			if($pag == $atual){
				$lista .= '<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $pag . ', \'' . $nome_pagina . '\')"><b>' . $pag . '</b></a></li>';
			}else{
				$lista .= '<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $pag . ', \'' . $nome_pagina . '\')">' . $pag . '</a></li>';
			}
		}

		$lista .= '		<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $proxima . ', \'' . $nome_pagina . '\')"><img src="shell/img/proxima.png" border="0"></a></li>
				   		<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $ultima . ', \'' . $nome_pagina . '\');"><img src="shell/img/ultima.png" border="0"></a></li>
				   </ul>';
		return $lista;
	}

	/**
	 * Gera Datagrid da página
	 * 
	 */
	public function GerarDataGrid(){
		$nome_pagina = ucfirst($this->ctrl->GetSistema()->GetPaginaAtual()->Nome());
		$nome_pagina_lowcase = strtolower($this->ctrl->GetSistema()->GetPaginaAtual()->Nome());

		//---------------- Criando a query
		$query = $this->ctrl->getDao()->CriaQuery();
		$query->from("{$this->ctrl->NomeModelo()} a");

		//---------------- Configurando os possíveis filtros
		if(sizeof($this->grid_filtros) > 0){
			$i = 0;
			foreach($this->grid_filtros as $campo => $valor){
				if($i == 0){
					if(is_int($valor)){
						$query->where("a.$campo = ?", $valor);
					}else{
						$nvalor = "%$valor%";
						$query->where("a.$campo like ?", $nvalor);
					}
					$i = 1;
				}else{
					if(is_int($valor)){
						$query->andWhere("a.$campo = ?", $valor);
					}else{
						$nvalor = "%$valor%";
						$query->andWhere("a.$campo like ?", $nvalor);
					}
				}
			}
		}

		//---------------- Configurando a Ordenação
		$ordem_acao = $this->ctrl->GetSistema()->GetParametros('ordem');
		$ordem_padrao = $this->ordenacao;

		if($ordem_acao && $ordem_padrao){
			$query->orderBy("a.$ordem_acao, a.$ordem_padrao ASC");
		}
		if($ordem_acao && !$ordem_padrao){
			$query->orderBy("a.$ordem_acao ASC");
		}
		if(!$ordem_acao && $ordem_padrao){
			$query->orderBy("a.$ordem_padrao ASC");
		}

		$pagina_corrente = ($this->ctrl->GetSistema()->GetParametros('corrente')) ? $this->ctrl->GetSistema()->GetParametros('corrente') : 1;
		$param_itens_por_pagina = ($this->ctrl->GetSistema()->GetParametros('itens_por_pagina')) ? $this->ctrl->GetSistema()->GetParametros('itens_por_pagina') : $this->itens_por_pagina;

		 //---------------- Criando a paginaçao
		$pager = new Doctrine_Pager($query, $pagina_corrente, $param_itens_por_pagina);
		$result = $pager->execute();
		if(sizeof($result) == 0){
			return "Nenhum registro encontrado";
		}

		$total_paginas = $pager->getLastPage();
		$paginacao = $pager->getRange('Sliding',array('chunk' => $this->extensao_paginacao));
		$total_registros = $pager->getNumResults();
		$em_torno = $paginacao->rangeAroundPage();
		$primeira_pagina = $pager->getFirstPage();
		$ultima_pagina	= $pager->getLastPage();
		$html_paginacao = $this->GerarPaginacao($pagina_corrente, $em_torno, $primeira_pagina, $ultima_pagina);

		//---------------- Gerando cabeçalho do datagrid
		$campos = $this->grid_campos;
		$cabecalho = '<tr class="table-header">';
		$lista_campos = array();
		$total_campos = sizeof($campos);
		$total_tabela = $total_campos + 1;

		foreach($campos as $campo){
			foreach($campo as $label => $content){
				if($label != 'mascara' && $label != "modelo" && $label != "tipo")
					$cabecalho .= "<td>$label</td>";
			}
		}

		$cabecalho .= "<td>Ação</td>";

		//---------------- Montando o select para exibição de itens por pagina
		if(sizeof($result) > 0){
			$options = '';
			for($i = 0; $i < 4; $i++){
				if($i == 0){
					if($param_itens_por_pagina == 20){
						$options .= "<option value='20' selected='selected'>20</option>";
					}else{
						$options .= "<option value='20'>20</option>";
					}
				}
				if($i == 1){
					if($param_itens_por_pagina == 50){
						$options .= "<option value='50' selected='selected'>50</option>";
					}else{
						$options .= "<option value='50'>50</option>";
					}
				}
				if($i == 2){
					if($param_itens_por_pagina == 100){
						$options .= "<option value='100' selected='selected'>100</option>";
					}else{
						$options .= "<option value='100'>100</option>";
					}
				}
				if($i == 3){
					if($param_itens_por_pagina == $total_registros){
						$options .= "<option value='$total_registros' selected='selected'>Todos</option>";
					}else{
						$options .= "<option value='$total_registros'>Todos</option>";
					}
				}
			}

			//---------------- montando o cabeçalho
			$tabela = '<table width="100%" cellpadding="2" cellspacing="0" id="table-list">';
			$html_pag_final = '<tr class="paginacao">
									<td colspan="' . $total_campos . '">
										' . $html_paginacao . '
									</td>
									<td>
										<select name="itens_por_pagina" id="itens_por_pagina" onchange="Sofia.ConfigItensPorPagina(this, \'' . $nome_pagina_lowcase . '\')">
												' . $options . '
										</select>
									</td>
								</tr>';
			$tabela .= $html_pag_final;
			$tabela .= $cabecalho;

			//---------------- Tabelando os dados
			/*
			 * Verifico aqui os arrays dos campos enviados, quais são as opções enviadas e tratando de acordo com o necessário
			 */
			foreach($result as $model){
				$tabela .= "<tr>";
				for($i = 0; $i < sizeof($campos); $i++){
					if(sizeof($campos[$i]) >= 2){
						$array = $campos[$i];
						foreach($array as $label => $content){
							if(!is_array($content)){
								$metodo = "get_$content"; // pega o nome do campo, transforma em metodo pra usar dentro do else
							}elseif($label == "mascara"){
								$tabela .= "<td>{$content[$model->$metodo()]}</td>";
							}elseif($label == "modelo"){
								@$valor_modelo_referenciado = $this->InstanciaModelo($model, $content["nome_modelo"], $content["metodo"], $content["indice"]);
								if(isset($content["tipo"]) && $content["tipo"] == "img"){
									$valor_final = $this->GeraImagemTag($valor_modelo_referenciado);
								}elseif(isset($content["tipo"]) && $content["tipo"] == "link"){
									$valor_final =  "<a href='{$valor_modelo_referenciado}' rel='me'>link</a>";
								}else{
									$valor_final = $valor_modelo_referenciado;
								}

								$tabela .= "<td>{$valor_final}</td>";
							}else{
								foreach($content as $chave => $valor){
									if($chave == "tipo"){
										if($valor == "img"){
											$valor_final = $this->GeraImagemTag($model->$metodo());
										}elseif($valor == "link"){
											$http = "http://";
											$www = "www";
											$retorno_metodo = $model->$metodo();

											if(is_int(strpos($retorno_metodo, $http))){
												$valor_final = "<td><a href='$retorno_metodo' rel='me'>Acessar</a></td>";
											}else{
												if(is_int(strpos($retorno_metodo, $www))){
													$valor_final = "<td><a href='{$http}{$retorno_metodo}' rel='me'>Acessar</a></td>";
												}else{
													$valor_final = "<td><a href='" . FILE_ROOT_FOLDER . $retorno_metodo . "' rel='me'>Baixar</a></td>";
												}
											}
										}
										$tabela .= $valor_final;
									}
								}
							}
						}
					}else{
						foreach($campos[$i] as $label => $content){
							$metodo = "get_$content";
							$valor_final = "<td>{$model->$metodo()}</td>";
							$tabela .= $valor_final;
						}
					}
				}

			//---------------- Configurando a célular de ações conforme configuração do usuário
				$tabela .= "<td>";
				foreach($this->acoes_permitidas as $acoes){
					$tmp_id = $model->id;
					if($acoes == 'editar'){
						$tabela .= "<a href='javascript:void(0);' onclick='Sofia.Editar({$tmp_id}, \"$nome_pagina_lowcase\")' title='Editar'><img src='shell/img/editar.jpg' border='0' /></a> ";
					}
					if($acoes == 'excluir'){
						$tabela .= "<a href='javascript:void(0);' onclick='Sofia.Excluir({$tmp_id}, \"$nome_pagina_lowcase\")' title='Editar'><img src='shell/img/deletar.jpg' border='0' /></a>";
					}
					$tmp_id = null;
				}

				$tabela .= '</td>';
				$tabela .= "</tr>";
			}

			$tabela .= $html_pag_final;
			$tabela .= '</table>';
			$lista_tabela = $tabela;
			return $lista_tabela;

		}else{
			return false;
		}
	}

	/*
	 * Este método é invocado quando a chave "modelo" é configurada no array de campos no controlador
	 * Com base dos dados enviados no array do campo, ele chama o modelo atrelado ao registro atual e invoca o método passado deste modelo retornando seu valor
	 */
 	private function InstanciaModelo($modelo, $ref_modelo, $ref_metodo, $indice = 0){

 		$sub_model_list = "get_$ref_modelo";
 		$sub_models = $modelo->$sub_model_list();

 		if($indice){
 			$sub_models = $sub_models[$indice];
 		}

 		$valor = $sub_models->$ref_metodo();

 		return $valor;
 	}

 	private function GeraImagemTag($valor){
 		$path_img = ROOT_IMG . $valor;
 		$img = "<img src='{$path_img}' width='100' height='80' border='0' onclick=\"Sofia.ShowImagem('Imagem', '{$path_img}')\" />";

 		return $img;
 	}
}